package quote

/*
#cgo CPPFLAGS: -fPIC -I./
#cgo linux LDFLAGS: -fPIC -L${SRCDIR}/../lib -Wl,-rpath ${SRCDIR}/../lib -ltapquote -lstdc++

#include "struct_cgo.h"

void* CreateQuoteAPINotify();
void* CreateQuoteAPI(struct TapAPIApplicationInfo *appInfo);
void FreeQuoteAPI(void* api);
void* GetQuoteAPIVersion();
int SetQuoteAPIDataPath(char* path);
int SetQuoteAPILogLevel(char level);

// ********************** 调用函数 ******************
int qSetAPINotify(void* api,void  *apiNotify);
int qSetHostAddress(void* api,char *IP,unsigned short port);
int qLogin(void* api,struct TapAPIQuoteLoginAuth *loginAuth);
int qDisconnect(void* api);
int qQryCommodity(void* api,unsigned int *sessionID);
int qQryContract(void* api,unsigned int *sessionID,struct TapAPICommodity *qryReq);
int qSubscribeQuote(void* api,unsigned int *sessionID,struct TapAPIContract *contract);
int qUnSubscribeQuote(void* api,unsigned int *sessionID,struct TapAPIContract *contract);



// ********************** 响应函数 ******************
void qSetOnRspLogin(void*, void*);
void qSetOnAPIReady(void*, void*);
void qSetOnDisconnect(void*, void*);
void qSetOnRspQryCommodity(void*, void*);
void qSetOnRspQryContract(void*, void*);
void qSetOnRspSubscribeQuote(void*, void*);
void qSetOnRspUnSubscribeQuote(void*, void*);
void qSetOnRtnQuote(void*, void*);


// Onxxx 为go 的 export所用
void OnRspLogin( int errorCode,  struct TapAPIQuotLoginRspInfo *info);
void OnAPIReady();
void OnDisconnect( int reasonCode);
void OnRspQryCommodity( unsigned int sessionID,  int errorCode,  char isLast,  struct TapAPIQuoteCommodityInfo *info);
void OnRspQryContract( unsigned int sessionID,  int errorCode,  char isLast,  struct TapAPIQuoteContractInfo *info);
void OnRspSubscribeQuote( unsigned int sessionID,  int errorCode,  char isLast,  struct TapAPIQuoteWhole *info);
void OnRspUnSubscribeQuote( unsigned int sessionID,  int errorCode,  char isLast,  struct TapAPIContract *info);
void OnRtnQuote( struct TapAPIQuoteWhole *info);


#include <stdlib.h>
#include <stdint.h>
*/
import "C"

import (
	"fmt"
	"unsafe"
)

var q *Quote

func NewQuote() *Quote {
	if q == nil {
		q = &Quote{}
	}
	return q
}

// Quote 行情接口
type Quote struct {
	api, spi unsafe.Pointer
	// 定义响应函数变量
	OnRspLogin            func(errorCode TAPIINT32, info *TapAPIQuotLoginRspInfo)
	OnAPIReady            func()
	OnDisconnect          func(reasonCode TAPIINT32)
	OnRspQryCommodity     func(sessionID TAPIUINT32, errorCode TAPIINT32, isLast TAPIYNFLAG, info *TapAPIQuoteCommodityInfo)
	OnRspQryContract      func(sessionID TAPIUINT32, errorCode TAPIINT32, isLast TAPIYNFLAG, info *TapAPIQuoteContractInfo)
	OnRspSubscribeQuote   func(sessionID TAPIUINT32, errorCode TAPIINT32, isLast TAPIYNFLAG, info *TapAPIQuoteWhole)
	OnRspUnSubscribeQuote func(sessionID TAPIUINT32, errorCode TAPIINT32, isLast TAPIYNFLAG, info *TapAPIContract)
	OnRtnQuote            func(info *TapAPIQuoteWhole)
}

func (q *Quote) CreateTapQuoteAPINotify() {
	q.spi = C.CreateQuoteAPINotify()
}
func (q *Quote) CreateTapQuoteAPI(appInfo *TapAPIApplicationInfo) {
	q.api = C.CreateQuoteAPI((*C.struct_TapAPIApplicationInfo)(unsafe.Pointer(appInfo)))
}
func (q *Quote) FreeTapQuoteAPI(api unsafe.Pointer) {
	C.FreeQuoteAPI(api)
}
func (q *Quote) GetTapQuoteAPIVersion() string {
	return C.GoString((*C.char)(C.GetQuoteAPIVersion()))
}
func (q *Quote) SetTapQuoteAPIDataPath(path string) C.int {
	return C.SetQuoteAPIDataPath(C.CString(path))
}
func (q *Quote) SetTapQuoteAPILogLevel(level byte) C.int {
	return C.SetQuoteAPILogLevel(C.char(level))
}

// 替代 SetAPINotify
func (q *Quote) SetSpi() { C.qSetAPINotify(q.api, q.spi) }

// ********************** 调用函数 ******************

func (q *Quote) SetAPINotify(apiNotify unsafe.Pointer) C.int {
	return C.qSetAPINotify(q.api, apiNotify)
}

func (q *Quote) SetHostAddress(IP string, port TAPIUINT16) C.int {
	return C.qSetHostAddress(q.api, C.CString(IP), C.ushort(port))
}

func (q *Quote) Login(loginAuth *TapAPIQuoteLoginAuth) C.int {
	return C.qLogin(q.api, (*C.struct_TapAPIQuoteLoginAuth)(unsafe.Pointer(loginAuth)))
}

func (q *Quote) Disconnect() C.int { return C.qDisconnect(q.api) }

func (q *Quote) QryCommodity(sessionID *TAPIUINT32) C.int {
	return C.qQryCommodity(q.api, (*C.uint)(unsafe.Pointer(sessionID)))
}

func (q *Quote) QryContract(sessionID *TAPIUINT32, qryReq *TapAPICommodity) C.int {
	return C.qQryContract(q.api, (*C.uint)(unsafe.Pointer(sessionID)), (*C.struct_TapAPICommodity)(unsafe.Pointer(qryReq)))
}

func (q *Quote) SubscribeQuote(sessionID *TAPIUINT32, contract *TapAPIContract) C.int {
	return C.qSubscribeQuote(q.api, (*C.uint)(unsafe.Pointer(sessionID)), (*C.struct_TapAPIContract)(unsafe.Pointer(contract)))
}

func (q *Quote) UnSubscribeQuote(sessionID *TAPIUINT32, contract *TapAPIContract) C.int {
	return C.qUnSubscribeQuote(q.api, (*C.uint)(unsafe.Pointer(sessionID)), (*C.struct_TapAPIContract)(unsafe.Pointer(contract)))
}

// ********************** 响应函数 ******************
func (q *Quote) RegCallBack() {
	C.qSetOnRspLogin(q.spi, C.OnRspLogin)
	C.qSetOnAPIReady(q.spi, C.OnAPIReady)
	C.qSetOnDisconnect(q.spi, C.OnDisconnect)
	C.qSetOnRspQryCommodity(q.spi, C.OnRspQryCommodity)
	C.qSetOnRspQryContract(q.spi, C.OnRspQryContract)
	C.qSetOnRspSubscribeQuote(q.spi, C.OnRspSubscribeQuote)
	C.qSetOnRspUnSubscribeQuote(q.spi, C.OnRspUnSubscribeQuote)
	C.qSetOnRtnQuote(q.spi, C.OnRtnQuote)

}

//export OnRspLogin
func OnRspLogin(errorCode C.int, info *C.struct_TapAPIQuotLoginRspInfo) {
	if q.OnRspLogin != nil {
		q.OnRspLogin(TAPIINT32(errorCode), (*TapAPIQuotLoginRspInfo)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRspLogin")
	}
}

//export OnAPIReady
func OnAPIReady() {
	if q.OnAPIReady != nil {
		q.OnAPIReady()
	} else {
		fmt.Println("OnAPIReady")
	}
}

//export OnDisconnect
func OnDisconnect(reasonCode C.int) {
	if q.OnDisconnect != nil {
		q.OnDisconnect(TAPIINT32(reasonCode))
	} else {
		fmt.Println("OnDisconnect")
	}
}

//export OnRspQryCommodity
func OnRspQryCommodity(sessionID C.uint, errorCode C.int, isLast C.char, info *C.struct_TapAPIQuoteCommodityInfo) {
	if q.OnRspQryCommodity != nil {
		q.OnRspQryCommodity(TAPIUINT32(sessionID), TAPIINT32(errorCode), TAPIYNFLAG(isLast), (*TapAPIQuoteCommodityInfo)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRspQryCommodity")
	}
}

//export OnRspQryContract
func OnRspQryContract(sessionID C.uint, errorCode C.int, isLast C.char, info *C.struct_TapAPIQuoteContractInfo) {
	if q.OnRspQryContract != nil {
		q.OnRspQryContract(TAPIUINT32(sessionID), TAPIINT32(errorCode), TAPIYNFLAG(isLast), (*TapAPIQuoteContractInfo)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRspQryContract")
	}
}

//export OnRspSubscribeQuote
func OnRspSubscribeQuote(sessionID C.uint, errorCode C.int, isLast C.char, info *C.struct_TapAPIQuoteWhole) {
	if q.OnRspSubscribeQuote != nil {
		q.OnRspSubscribeQuote(TAPIUINT32(sessionID), TAPIINT32(errorCode), TAPIYNFLAG(isLast), (*TapAPIQuoteWhole)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRspSubscribeQuote")
	}
}

//export OnRspUnSubscribeQuote
func OnRspUnSubscribeQuote(sessionID C.uint, errorCode C.int, isLast C.char, info *C.struct_TapAPIContract) {
	if q.OnRspUnSubscribeQuote != nil {
		q.OnRspUnSubscribeQuote(TAPIUINT32(sessionID), TAPIINT32(errorCode), TAPIYNFLAG(isLast), (*TapAPIContract)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRspUnSubscribeQuote")
	}
}

//export OnRtnQuote
func OnRtnQuote(info *C.struct_TapAPIQuoteWhole) {
	if q.OnRtnQuote != nil {
		q.OnRtnQuote((*TapAPIQuoteWhole)(unsafe.Pointer(info)))
	} else {
		fmt.Println("OnRtnQuote")
	}
}
